import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report

# 设置 Matplotlib 中文显示（可选）
matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # Windows 使用 SimHei
matplotlib.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 1. 加载数据集（Iris 鸢尾花数据集）
iris = datasets.load_iris()
X = iris.data[:, :2]  # 取前两个特征（花萼长度、花萼宽度）
y = (iris.target == 0).astype(int)  # 只分类是否为 "山鸢尾"（1: 是, 0: 不是）

# 2. 数据集划分（80% 训练，20% 测试）
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 3. 数据标准化（逻辑回归对数值范围敏感）
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 4. 训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)

# 5. 预测
y_pred = model.predict(X_test)
y_prob = model.predict_proba(X_test)[:, 1]  # 获取类别 1 的概率

# 6. 评估模型
accuracy = accuracy_score(y_test, y_pred)
conf_matrix = confusion_matrix(y_test, y_pred)
report = classification_report(y_test, y_pred)

print(f"模型准确率: {accuracy:.4f}")
print("\n混淆矩阵:\n", conf_matrix)
print("\n分类报告:\n", report)

# 7. 结果可视化（决策边界）
def plot_decision_boundary(X, y, model):
    h = .02
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
    Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)

    plt.contourf(xx, yy, Z, alpha=0.3)
    sns.scatterplot(x=X[:, 0], y=X[:, 1], hue=y, palette=['blue', 'red'], edgecolor='k')
    plt.xlabel("花萼长度")
    plt.ylabel("花萼宽度")
    plt.title("逻辑回归决策边界")
    plt.show()

plot_decision_boundary(X_train, y_train, model)
